<?php
/*
 * Created on 16.8.2006
 */
 
class cException extends Exception {

	public 	$secret = array(
								0 => array('class'=>'aAdmin', 'function'=>'__construct'),
								1 => array('class'=>'cCMS', 'function'=>'__construct'),
								2 => array('class'=>'standard_user', 'function'=>'handleLogin'));
							
	static $first = true;	
	public $isFirst = false;							

	function __construct($message, $solution='Don\'t worry, be happy. Issue will be sent to administrator.') 
	{
		if (self::$first) {
			self::$first = false;
			$this->isFirst = true;
		}	
		parent::__construct($message);
		$this->solution = $solution;
	}

	
	function __toString() 
	{		
		$style="
			/* 
			html { padding:16px; background:#eee; }
			body { padding:16px; background:#fff; font-family: verdana; }
			*/
			h1,h2,h3 { font-family:'Trebuchet MS', Helvetica; border-bottom:1px solid red; }
			tr th, tr td { border-bottom:1px solid #bbb; padding:4px; }
			.file { color:#888; }
			.class { color:#707; font-weight:bold; }

			.trace { line-height:150%; }

			.args .class { color:black; }
			.args .string { color:#00f; }
		";
		
		
		$e['solution'] = $this->solution;                  // code of exception
		$e['file'] = $this->getFile();                  // source filename
		$e['line'] = $this->getLine();                  // source line
		$e['trace'] = "<pre class=\"trace\">".$this->getMyTrace()."</pre>";          // formated string of trace

		$s[] = '<table>';
		foreach ($e as $k=>$v) {
			$s[]="<tr><th>$k</th><td>$v</td></tr>";
		}
		$s[] = '</table>';

		// Pokud jsme prvni
		if ($this->isFirst) 
		{
			header('HTTP/1.1 500 Internal Server Error');
			$message[] = "<html>\n<head>\n<style>$style</style></head>\n<body>";
			$message[]='<style>'.$style.'</style>';
		}	
		$message[] = "<h1>Chyba : ".$this->getMessage()." </h1><p> ".implode("\n\t\t",$s)." </p>\n</html>";
		
		return implode('',$message);		
	}
	
	function getMyTrace() 
	{
		
		$trace = $this->stripsecret($this->getTrace());
		
		$dirLen = strpos(str_replace('\\','/',dirname(__FILE__)),'/cms/core')+1; 
		
		foreach ($trace as $step => $t) 
		{
			$a = array();
			foreach ($t['args'] as $k=>$v) {
				if (is_object($v)) {
					$a[] = '<span class="class">'.get_class($v).'</span>'; 
				} else if (is_array($v)) {
					$a[] = '<span class="array">'.print_r($v, true).'</span>'; 
				} else if (!is_int($v)) {
					$a[] = '<span class="string">\''.$v.'\'</span>';
				} else {
					$a[] = $v;
				}
			}
			$args = implode(', ',$a);
			
			$s[] = '#'.$step.' <span class="class">'.$t['class'].'</span>'.$t['type'].$t['function'].'(<span class="args">'.$args.'</span>) <span class="file">'.substr(str_replace('\\','/',$t['file']),$dirLen).'('.$t['line'].')</span>';
		}
		return implode("\n",$s);
	}
	
	function stripSecret($trace) 
	{
		foreach ($trace as $k=>$t) {
			foreach ($this->secret as $secret) {
				foreach ($secret as $key => $val) {
					if ($t[$key]==$val) {
						unset($trace[$k]);
						break;
					}
				}	
			}
		}
		return $trace;
	}

} 

function exceptions_error_handler($severity, $message, $filename, $lineno) 
{
	if ($severity<8) {
		$e = new cException($message); //, $severity, $filename, $lineno);
		echo $e->__toString();
		die();
	}
}


function exception_handler($exception) 
{
	echo $exception->__toString();
	die();
}

set_error_handler('exceptions_error_handler');
set_exception_handler('exception_handler');
 
?>
